/*
 * The RavenX Library
 * Copyright (c) 2008 by Solidus
 * 
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.It is provided "as is" without express 
 * or implied warranty.
 */


#ifndef RX_AUTOMATON_H
#define RX_AUTOMATON_H

#include "rx_typedef.h"
#include "rx_vector.h"

RX_SPACE_BEG




typedef struct __rx_edge_tag			rx_edge_t;
typedef struct __rx_state_tag			rx_state_t;



typedef struct __rx_automaton_tag		rx_automaton_t;


RavenAPI rx_state_t*	rx_automaton_edge_from(rx_edge_t *edge);
RavenAPI rx_state_t*	rx_automaton_edge_to(rx_edge_t *edge);

RavenAPI void*			rx_automaton_edge_data(rx_edge_t *edge);
RavenAPI void*			rx_automaton_state_data(rx_state_t *state);
RavenAPI size_t			rx_automaton_state_edge_count(rx_state_t *state, rx_bool is_out);
RavenAPI rx_edge_t*		rx_automaton_state_edge(rx_state_t *state, size_t idx, rx_bool is_out);

RavenAPI rx_int_n		rx_automaton_state_edge_indexof(rx_state_t *state, rx_bool is_out, const rx_edge_t *edge);

RavenAPI void			rx_automaton_state_edge_swap_order(rx_state_t *state, rx_bool is_out, size_t l, size_t r);

RavenAPI void	rx_automaton_state_edge_move_to(rx_state_t *state, rx_bool is_out, size_t l, size_t r);

RavenAPI void			rx_automaton_state_edge_put_front(rx_state_t *state, rx_bool is_out, size_t idx);
RavenAPI void			rx_automaton_state_edge_put_back(rx_state_t *state, rx_bool is_out, size_t idx);



RavenAPI rx_automaton_t* rx_automaton_create(const rx_info_t *state_info, const rx_info_t *edge_info, const rx_alloc_t *palloc);

RavenAPI void rx_automaton_destroy(rx_automaton_t *atm);

RavenAPI void rx_automaton_trim_mem(rx_automaton_t *atm);

RavenAPI rx_state_t* rx_automaton_alloc(rx_automaton_t *atm, const void *state_data);

RavenAPI rx_edge_t* rx_automaton_connect(rx_automaton_t *atm, rx_state_t *start, rx_state_t *end, const void *edge_data);
RavenAPI rx_edge_t* rx_automaton_connect_pos(rx_automaton_t *atm, rx_state_t *start, size_t pos, rx_state_t *end, const void *edge_data);

RavenAPI void rx_automaton_disconnect_edge(rx_automaton_t *atm, rx_state_t *start, rx_edge_t *edge);

RavenAPI void rx_automaton_disconnect(rx_automaton_t *atm, rx_state_t *state);









/***************************************************************utility**********************************************************************/





typedef struct __rx_atm_copy_result_tag
{
		rx_vector_t		*dest;
		rx_vector_t		*sour;
}rx_atm_copy_result_t;

RavenAPI rx_vector_t* rx_automaton_path(rx_automaton_t *atm, rx_state_t *root, rx_bool (*edge_test_f)(const rx_edge_t*));
RavenAPI rx_vector_t* rx_automaton_acyclic_path(rx_automaton_t *atm, rx_state_t *root, rx_bool (*edge_test_f)(const rx_edge_t*));
RavenAPI rx_atm_copy_result_t rx_automaton_copy_state(rx_automaton_t *atm, rx_state_t *root, rx_bool (*edge_test_f)(const rx_edge_t*));

#define rx_atm_destroy_copy_result(pres) do{rx_vector_destroy((pres)->dest); rx_vector_destroy((pres)->sour); }while(0)




RX_SPACE_END









#endif


